﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Text;

namespace M
{
	/// <summary>
	/// MException
	/// </summary>
	[Serializable]
	public class MException : Exception, ISerializable
	{
		/// <summary>
		/// M 提供的自定义 Exception
		/// 默认严重级别为：Message
		/// 默认原始异常为：Null
		/// </summary>
		/// <param name="message">所包含的消息</param>
		public MException(string message)
			: this(message, MExceptionLevel.Message)
		{

		}
		/// <summary>
		/// M 提供的自定义 Exception
		/// 默认原始异常为：Null
		/// </summary>
		/// <param name="message">所包含的消息</param>
		/// <param name="exceptionLevel">所对应的严重级别</param>
		public MException(string message, MExceptionLevel exceptionLevel)
			: this(message, exceptionLevel, null)
		{
		}
		/// <summary>
		/// M 提供的自定义 Exception
		/// </summary>
		/// <param name="message">所包含的消息</param>
		/// <param name="exceptionLevel">所对应的严重级别</param>
		/// <param name="innerException">对包含的原始异常</param>
		public MException(string message, MExceptionLevel exceptionLevel, Exception innerException)
			: base(message, innerException)
		{
			this.Level = exceptionLevel;
			try
			{
				switch (this.Level)
				{
					case MExceptionLevel.Stop:
						MLogger.Error(message, innerException);
						break;
					case MExceptionLevel.Fatal:
						MLogger.Fatal(message, innerException);
						break;
				}
			}
			catch { }
		}

		/// <summary>
		/// 此异常所对应的严重级别
		/// </summary>
		public MExceptionLevel Level { get; set; }

		private MException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			this.Level = (MExceptionLevel)info.GetValue("Level", typeof(MExceptionLevel));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="info"></param>
		/// <param name="context"></param>
		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		protected new virtual void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			info.AddValue("Level", this.Level);
			base.GetObjectData(info, context);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="info"></param>
		/// <param name="context"></param>
		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			if (info == null)
				throw new ArgumentNullException("info");

			GetObjectData(info, context);
		}
	}
}
